#pragma once
#include <iostream>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <string>
#include <unistd.h>
#include <cstring>
#include "Time.hpp"
#include <cstdio>

const std::string gpath = "/home/dpj/linux_code/Review/ShareMemory"; // 必须是已经存在的文件路径！！
const int gpro = 0x6666;
const mode_t gmode = 0600;
const int gsize = 4097;


struct data{
    char status[32];
    char lastime[64];
    char text[1024];
};

std::string ToHex(int n)
{
    char buffer[64];
    // 自动添加 \0
    snprintf(buffer, sizeof(buffer), "0x%x", n);
    return buffer;
}

class ShareMemory
{
private:
    void CreateShmHelper(int flags)
    {
        _key = ::ftok(gpath.c_str(), gpro);
        if (_key < 0)
        {
            std::cout << "错误原因： " << strerror(errno) << std::endl;
            std::cerr << "ftok error" << std::endl;
            exit(0);
        }
        std::cout << "_key: " << ToHex(_key) << std::endl;
        _shmid = ::shmget(_key, gsize, flags);
        if (_shmid < 0)
        {
            std::cerr << "shmget error" << std::endl;
            return ;
        }
        std::cout << "shmget id: " << _shmid << std::endl;
    }

public:
    ShareMemory() {
        
    }
    ~ShareMemory() {}
    void CreateShm(){
        CreateShmHelper(IPC_CREAT|IPC_EXCL|gmode);
    }
    void GetShm(){
        CreateShmHelper(IPC_CREAT);
    }
    void ShmAt(){
        _ret = ::shmat(_shmid,nullptr,0);
        std::cout << "shmat done, ret: " << (long long)_ret << std::endl;
    }
    void ShmDt(){
        ::shmdt(_ret);
        std::cout << "shmshmdtat done"  << std::endl;
    }
    void DeleteShm(){
        ::shmctl(_shmid,IPC_RMID,nullptr);
        std::cout << "delete shm done"  << std::endl;
    }
    void* GetAddr(){return _ret;}
    //获取相关属性
    void SheMeta(){
        struct shmid_ds buffer;
        int n = ::shmctl(_shmid,SHM_STAT,&buffer);
        if (n < 0){
            std::cerr << "获取信息失败" << std::endl;
            return ;
        }
        std::cout << "########################################" << std::endl;
        std::cout << buffer.shm_ctime << std::endl; 
        std::cout << buffer.shm_lpid << std::endl;
        std::cout << buffer.shm_nattch << std::endl;
        std::cout << "########################################" << std::endl;
    }
private:
    int _shmid;
    void* _ret;
    key_t _key;
};



ShareMemory Shm;